package com.itheima.ydd.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.ydd.common.R;
import com.itheima.ydd.dto.*;
import com.itheima.ydd.dto.UserDataDto.UserDataHotDto;
import com.itheima.ydd.dto.UserDataDto.UserDataListDto;
import com.itheima.ydd.dto.UserDataDto.UserDataNewDto;
import com.itheima.ydd.entity.*;
import com.itheima.ydd.entity.sysconfig.SysAllConfig;
import com.itheima.ydd.exception.ConsumerException;
import com.itheima.ydd.service.*;
import com.itheima.ydd.service.impl.YddArticleServiceImpl;
import com.itheima.ydd.utils.AppJwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@RestController
@Slf4j
@RequestMapping("index")
public class IndexController {
    @Autowired
    IndexService service;
    @Autowired
    ConfigService configService;
    @Autowired
    CateService cateService;
    @Autowired
    YddArticleService articleService;
    @Autowired
    AdvposService advposService;
    @Autowired
    YddTagService tagService;
    @Autowired
    YddUserService userService;
    @Autowired
    AdvimgService advimgService;

    @PostMapping("login")
    public ResponseEntity<Result> login(@RequestBody SysUser user) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getLogin_name, user.getLogin_name());
        SysUser user1 = service.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(user1)) {
            throw new ConsumerException("该用户不存在");
        }
        String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        if (!user1.getPassword().equals(password)) {
            throw new ConsumerException("该用户不存在");
        }
        if (user1.getStatus() == 0) {
            throw new ConsumerException("该用户已被禁用!");
        }
        Map tokenMap = new HashMap<>();
        tokenMap.put("id", user1.getId());
        String token = AppJwtUtil.getToken(tokenMap);
        HashMap<String, String> map = new HashMap<>();
        map.put("token", token);
        return ResponseEntity.ok(new Result(0, "", map));
    }

    @PostMapping("profile")
    public ResponseEntity<Result> profile() {
        Map<String, Object> map = service.profile();
        return ResponseEntity.ok(new Result(0, "", map));
    }

    @GetMapping("getConfig")
    public ResponseEntity<Result> getConfig() {
        List<Config> list = configService.list();

        Map<String, String> map = new HashMap<>();
        for (Config config : list) {
            map.put(config.getAttrKey(), config.getAttrValue());
        }
        return ResponseEntity.ok(new Result(0, "", map));
    }

    @GetMapping("/baseInfo")
    public ResponseEntity<Result> baseInfo() {

        BaseInfoDto baseInfoDto = new BaseInfoDto();
        baseInfoDto.setArticleNum(0);

        // 所有分类数据
        List<CateDto> cateDtoList = cateService.list().stream().map(cate -> {
            CateDto cateDto = new CateDto();
            BeanUtils.copyProperties(cate, cateDto);
            LambdaQueryWrapper<YddArticle> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(YddArticle::getCateid, cate.getId());
            int count = articleService.count(queryWrapper);
            cateDto.setNum(count);
            // 文章总数
            baseInfoDto.setArticleNum(baseInfoDto.getArticleNum() + count);
            return cateDto;
        }).collect(Collectors.toList());
        baseInfoDto.setAllCateList(cateDtoList);

        // 广告位总数
        baseInfoDto.setAdvposNum(advposService.count());

        // 标签总数
        baseInfoDto.setTagNum(tagService.count());

        // 管理员总数
        baseInfoDto.setAdminNum(userService.count());

        // 广告分类总数
        baseInfoDto.setCateNum(cateDtoList.size());

        // 广告图总数
        baseInfoDto.setAdvimgNum(advimgService.count());

        {
            // 最新用户数据
            LambdaQueryWrapper<YddUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(YddUser::getId, YddUser::getUsername, YddUser::getSex, YddUser::getAddress, YddUser::getIcon);
            // 默认数据
            // queryWrapper.eq(YddUser::getDefaultData, 1);
            queryWrapper.orderByDesc(YddUser::getId);
            queryWrapper.last("limit 7");
            baseInfoDto.setNewUserList(userService.list(queryWrapper));
        }

        {
            // 热门文章数据
            LambdaQueryWrapper<YddArticle> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(YddArticle::getId, YddArticle::getTitle, YddArticle::getAuthor, YddArticle::getKeywords, YddArticle::getClick);
            queryWrapper.orderByDesc(YddArticle::getClick);
            queryWrapper.last("limit 7");
            baseInfoDto.setHotArticleList(articleService.list(queryWrapper));
        }

        {
            // 用户数据
            UserDto userDto = new UserDto();
            LambdaQueryWrapper<YddUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(YddUser::getSex, 0);
            int womanNum = userService.count(queryWrapper);
            int allNum = userService.count();
            userDto.setTotal(allNum);
            userDto.setUserWoman(womanNum);
            userDto.setUserMan(allNum - womanNum);
            baseInfoDto.setUser(userDto);
        }

        return ResponseEntity.ok(new Result(0, "", baseInfoDto));
    }


    //-----------------------------------------------
    @Autowired
    private YddCateService yddCateService;
    @Autowired
    private YddTagService yddTagService;
    @Autowired
    private YddLinkService yddLinkService;
    @Autowired
    private SysConfigService sysConfigService;

    @GetMapping("index")
    public R<QFindAll> index() {
        QFindAll qFindAll = new QFindAll();
        //这里搜集list数据
        //所有内容分类
        List<YddCate> allCate = yddCateService.list();
        //所有标签分类
        List<YddTag> allTag = yddTagService.list();
        //站点配置
        Result result = sysConfigService.allConfig();
        SysAllConfig sysAllConfig = (SysAllConfig) result.getData();
        List<SysAllConfig> sysAllConfigList = new ArrayList<>();
        sysAllConfigList.add(sysAllConfig);
        //链接
        List<YddLink> yddLinklist = yddLinkService.list();
        //banner:advimg首页Banner
        LambdaQueryWrapper<Advimg> advimgLambdaQueryWrapper1 = new LambdaQueryWrapper<Advimg>();
        advimgLambdaQueryWrapper1.eq(Advimg::getAdvimgpos, "15");
        List<Advimg> advimgList1 = advimgService.list(advimgLambdaQueryWrapper1);
        //sideBanner首页小广告位
        LambdaQueryWrapper<Advimg> advimgLambdaQueryWrapper2 = new LambdaQueryWrapper<Advimg>();
        advimgLambdaQueryWrapper2.eq(Advimg::getAdvimgpos, "14");
        List<Advimg> advimgList2 = advimgService.list(advimgLambdaQueryWrapper2);
        //详情页广告位1,2
        LambdaQueryWrapper<Advimg> advimgLambdaQueryWrapper3 = new LambdaQueryWrapper<Advimg>();
        advimgLambdaQueryWrapper3.eq(Advimg::getAdvimgpos, "12").or();
        advimgLambdaQueryWrapper3.eq(Advimg::getAdvimgpos, "13");
        List<Advimg> advimgList3 = advimgService.list(advimgLambdaQueryWrapper3);


        //--------------------------
        //这里封装list数据
        qFindAll.setAllTag(allTag);
        qFindAll.setAllCate(allCate);
        qFindAll.setAllLink(yddLinklist);
        qFindAll.setBanner(advimgList1);
        qFindAll.setSideBanner(advimgList2);
        qFindAll.setShowBanner(advimgList3);
        qFindAll.setConfig(sysAllConfigList);

        return R.success(qFindAll);

    }

    @Autowired
    private YddArticleService yddArticleService;


    //查询
    @GetMapping("new")
    public R<UserDataNewDto> neww(String page, String limit) {
        //获取系统当前时间
        long nowTime = new Date().getTime();
        log.info("当前时间是" + nowTime);

        //获取一周之前的毫秒值
        long endWeekTime = nowTime - 604800000L;
        //获取24小时之前的毫秒值
        long endDayTime = nowTime - 86400000L;

        //获取24小时最新文章数量
        LambdaQueryWrapper<YddArticle> yddArticleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddArticleLambdaQueryWrapper.ge(YddArticle::getCreate_date, endDayTime);
        int countday = yddArticleService.count(yddArticleLambdaQueryWrapper);
        //获取一周内最新文章
        LambdaQueryWrapper<YddArticle> yddArticleLambdaQueryWrapper2 = new LambdaQueryWrapper<>();
        yddArticleLambdaQueryWrapper.ge(YddArticle::getCreate_date, endWeekTime);
        int countweek = yddArticleService.count(yddArticleLambdaQueryWrapper2);
        //获取分页
//        PageDto<YddArticle> pageInfo = new PageDto<>(page, limit);
//        yddArticleService.page(pageInfo);
        //页码
        long pageLong = Long.parseLong(page);
        //  每页数量
        long limitLong = Long.parseLong(limit);
        PageDto<YddArticle> pageInfo = new PageDto<YddArticle>(pageLong, limitLong);
        PageDto<YddArticleDto> yddArticleDtoPageDto = new PageDto<>();
        yddArticleService.page(pageInfo);
        //吧分页过后的实体类小。传给分页类YddArticleDto
        BeanUtils.copyProperties(pageInfo, yddArticleDtoPageDto, "records");
        //-----------------------
        //分页实体类小获取所有的数据
        List<YddArticle> records = pageInfo.getdata();
        List<YddArticleDto> articleDtos = new ArrayList<>();
        for (YddArticle record : records) {
            //获取到每个数据对应的cateName
            Integer cateid = record.getCateid();
            Cate cate = cateService.getById(cateid);
            String cateName = cate.getCateName();
            //将cateName传输给一个YddArticleDto对象
            YddArticleDto yddArticleDto = new YddArticleDto();
            BeanUtils.copyProperties(record, yddArticleDto);
            yddArticleDto.setCatename(cateName);
            articleDtos.add(yddArticleDto);
        }


        //-----------------------
        yddArticleDtoPageDto.setRecords(articleDtos);
        //封装
        UserDataNewDto userDataNewDto = new UserDataNewDto();
        userDataNewDto.setNum_day(countday);
        userDataNewDto.setNum_week(countweek);
        userDataNewDto.setDesc("首页大列表");
        userDataNewDto.setList(yddArticleDtoPageDto);
        //再封装进R对象
        return R.success(userDataNewDto);

        //创建DTO对象,其中有属性desc: "首页大列表"  ,num_day,num_week ,  名字为list的pageDto对象
        //拿到创建时间ydd_article的create date时间和现在的时间判断.如果小于一周,那就拿出数据,计算数量x,将返回的类中的num_day属性赋值为这个数量x
        //如果小于24小时,就返回拿出数据,计算数量y,将返回的类中的num_week属性赋值为这个数量y
        //将page,limit传入查找所有,封装进pageDto,用R对象.success返回
    }

    //查询
    @GetMapping("/list")
    public ResponseEntity<Result> list(Integer page, Integer limit, Integer cateid) {
        //根据cateid(文章分类id)查询,查到的直接pageDto对象封装,然后存进list集合 (注意这里的返回名称也叫list)
        PageDto<YddArticle> pg = new PageDto<>(page, limit);
        LambdaQueryWrapper<YddArticle> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(!ObjectUtils.isEmpty(cateid), YddArticle::getCateid, cateid);
        articleService.page(pg, wrapper);
        PageDto<YddArticleDto> dpg = new PageDto<>();
        BeanUtils.copyProperties(pg, dpg, "records");
        List<YddArticleDto> list = new ArrayList<>();
        List<YddArticle> yddArticles = pg.getdata();
        for (YddArticle yddArticle : yddArticles) {
            Cate cate = cateService.getById(cateid);
            YddArticleDto dto = new YddArticleDto();
            BeanUtils.copyProperties(yddArticle, dto);
            dto.setCatename(cate.getCateName());
            list.add(dto);
        }
        dpg.setRecords(list);
        UserDataListDto listDto = new UserDataListDto();
        listDto.setList(dpg);
        //然后塞进R.success返回,查询失败返回R.error("失败")
        return ResponseEntity.ok(new Result(0, "", listDto));
    }

    @Autowired
    private YddUserService yddUserService;

    //注册
    @PostMapping("/reg")
    public R<String> reg(@RequestBody YddUser yddUser) {
        //将ydduser存入数据库,并返回R.seccess("注册成功")和token,这里的token从responseHeaders里获取
        //将ydduser存入数据库,并返回R.seccess("注册成功"),这里的token从responseHeaders里获取
        //判断账号存在就返回R对象.error("账号已存在")
        LambdaQueryWrapper<YddUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YddUser::getMobile, yddUser.getMobile());
        YddUser user1 = yddUserService.getOne(queryWrapper);
        if (!ObjectUtils.isEmpty(user1)) {
            throw new ConsumerException("账号已存在");
        }
        yddUser.setUsername("随机昵称" + UUID.randomUUID());
        yddUserService.save(yddUser);

        return R.success("注册成功");
    }

    //最新文章
    @GetMapping("/hot")
    public ResponseEntity<Result> hot() {
        //先创建一个Dto.里面包含一个String类型的名字叫desc的参数,参数值就是"侧边最新文章"字符串,和一个名字叫list的集合,泛型是Yddarticle
        //根据yddcate表的vatename 和yddarticle表的cateid进行操作,返回的值包含catename,id,title,pic,lovenum参数,传入list集合
        //返回R.seccess(Dto对象)
        UserDataHotDto hotDto = new UserDataHotDto();
        hotDto.setDesc("侧边最新文章");
        LambdaQueryWrapper<YddArticle> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(YddArticle::getLovenum);
        List<YddArticleDto> list = new ArrayList<>();
        List<YddArticle> yddArticles = yddArticleService.list(wrapper);
        for (int i = 0; i < 6; i++) {
            Cate cate = cateService.getById(yddArticles.get(i).getCateid());
            YddArticleDto articleDto = new YddArticleDto();
            BeanUtils.copyProperties(yddArticles.get(i), articleDto);
            articleDto.setCatename(cate.getCateName());
            list.add(articleDto);
        }
        hotDto.setList(list);
        return ResponseEntity.ok(new Result(0, "", hotDto));
    }

    @GetMapping("/recommend")
    public R<UserDataHotDto> recommend() {
        //先取出所有的数据封装成集合
        List<YddArticle> yddArticleList = yddArticleService.list();
        List<YddArticleDto> articleDtos = new ArrayList<>();
        for (YddArticle record : yddArticleList) {
            //获取到每个数据对应的cateName
            Integer cateid = record.getCateid();
            Cate cate = cateService.getById(cateid);
            String cateName = cate.getCateName();
            //将cateName传输给一个YddArticleDto对象
            YddArticleDto yddArticleDto = new YddArticleDto();
            BeanUtils.copyProperties(record, yddArticleDto);
            yddArticleDto.setCatename(cateName);
            articleDtos.add(yddArticleDto);
        }
        UserDataHotDto userDataHotDto = new UserDataHotDto();
        userDataHotDto.setDesc("侧边推荐文章");
        userDataHotDto.setList(articleDtos);
        return R.success(userDataHotDto);
    }

    @GetMapping("/show")
    public ResponseEntity<Result> findById(Integer id) {
        return service.findById(id);
    }

}
